﻿#region Opis pliku
//-----------------------------------------------------------------------------
// Helicopter.cs
// Autor: Jan Fraś
// 30.10.2012
//-----------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace pogra
{
    /// <summary>
    /// klasa helikoptera
    /// </summary>
    class Helicopter:Aircraft
    {
        #region pola
        Texture2D texture;
        float realrotation;
        int last_missile = Rand.next(0, 1000);
        int missileInterval = 2000;
        int missilerange = 800;
        int missilepower = 500;

        #endregion

        #region inicjalizacja
        public Helicopter(Vector2 pos, float rotation, int team, Texture2D texture, Texture2D particletexture, List<Unit> enemyteam) :
            base(pos, rotation, team, enemyteam)
        {
            this.texture = texture;
            this.particletexture = particletexture;
            hp = 1000;
            maxhp = hp;
            attackPower = 10;
            upgradeQuant = 5;
            this.team = team;
            range = 400;
            shotrange = 500;
            this.velocity = 0;
            shotInterval = 20;
            maxvelocity = 0.7f;
            realrotation = 0f;
            ExperienceLimit = 800;
        }
        #endregion

        #region logika różna
        protected override bool attack()
        {
            float temp = -realrotation + (float)((Math.Atan2(enemy.Position.Y - position.Y, enemy.Position.X - position.X) + Math.PI * 2) % (Math.PI * 2));
            while (temp > Math.PI)
                temp -= (float)Math.PI * 2;
            while (temp < -Math.PI)
                temp += (float)Math.PI * 2;

            if(base.attack() && Math.Abs(temp) < 0.05)
            {
                particleSystem.AddEmitter(new HelicopterShotEmitter(position + new Vector2((float)(30 * Math.Cos(realrotation)), (float)(30 * Math.Sin(realrotation))), particletexture, realrotation));
                lastshottime = lifetime;
                Bullet tmp = new Bullet(attackPower, realrotation, enemy, this,particleSystem);
                bulletmanager.add(tmp);
            }

            if ((enemy.Position - position).Length() < missilerange && last_missile < lifetime - missileInterval)
            {
                last_missile = lifetime;
                Missile tmp = new Missile(missilepower, realrotation, enemy, this, particleSystem);
                bulletmanager.add(tmp);
            }
            


            return  true;
        }

        public override bool move(TimeSpan deltat)
        {
            float tmp2;
            if (enemy == null)
                tmp2 = -realrotation + rotation;
            else
                tmp2 = -realrotation + (float)((Math.Atan2(enemy.Position.Y - position.Y, enemy.Position.X - position.X) + Math.PI * 2) % (Math.PI * 2));

            while (tmp2 > Math.PI)
                tmp2 = -(float)Math.PI * 2 + tmp2;
            while (tmp2 < -Math.PI)
                tmp2 = +(float)Math.PI * 2 + tmp2;

            if (Math.Abs(tmp2) < 0.04f)
                realrotation += tmp2;
            else
                realrotation += Math.Abs(tmp2) / tmp2 * 0.04f;
            
            return base.move(deltat);
        }

        protected override bool setvaluesTravelMode()
        {
            return setvalues();
        }

        protected override void upgrade()
        {
            missilepower = (int)((float)missilepower*1.2f);
            missileInterval -= 100;
            base.upgrade();
        }

        protected override bool setvalues()
        {
            Vector2 tmpdestination;
            int tmprange;

            if (enemy == null || flags.GoalPositionToReach == true)
            {
                tmpdestination = GoalPosition;
                tmprange = (int)(400f*velocity + 5);
            }
            else
            {
                tmpdestination = enemy.Position;
                tmprange = (int)range;
            }

            float tmp = -rotation + (float)((Math.Atan2(tmpdestination.Y - position.Y, tmpdestination.X - position.X) + Math.PI * 2) % (Math.PI * 2));
            
         
            
            if (velocity == 0)
            {
                rotation += tmp;
                rotationspeed = 0f;
            }
            else
            {
                //tmp należy od -pi do pi:

                if (tmp > Math.PI)
                    tmp = -(float)Math.PI * 2 + tmp;
                else
                    if (tmp < -Math.PI)
                        tmp = +(float)Math.PI * 2 + tmp;

                if (Math.Abs(tmp) > Math.PI * 0.9) rotationspeed = (float)1 / 80f;//tmp = (float)Math.PI*0.9f*Math.Sign(tmp);

                if (Math.Abs(rotationspeed) < Math.Abs(Math.Sin(tmp / 3) / 100f))
                    rotationspeed -= Math.Sign(tmp) / 400f;
                else
                    rotationspeed = (float)Math.Sin(tmp / 3) / 100f;
            }

            


            if ((position - tmpdestination).Length() > tmprange && velocity < maxvelocity)
            {
                velocity += 0.006f;

            }
            else
                if ((position - tmpdestination).Length() < tmprange)
                {
                    velocity *= 0.7f;

                    //if ((position - tmpdestination).Length() < 15 * tmprange * velocity)
                        //velocity = velocity * ( 0.3f + (float)Math.Cos(tmp)) / 1.3f;

                    if (Math.Abs(velocity) < maxvelocity / 30f)
                    {
                        velocity = 0;
                        return true;
                    }
                    else
                        return false;
                    
                }
            //if (velocity > maxvelocity * (float)Math.Cos(tmp)) velocity -= 0.015f ;

            
            return false;
        }

        public override int takehit(int hit, float attackrotation)
        {
            particleSystem.AddEmitter(new HitEmitter(position - new Vector2((float)(20 * Math.Cos(attackrotation)), (float)(20 * Math.Sin(attackrotation))), attackrotation));
            return base.takehit(hit, attackrotation);
        }
        #endregion

        #region metody stanów
        protected override void IdleState(TimeSpan deltat)
        {
            if (findtarget())
                State = UnitState.Attacking;
            base.IdleState(deltat);
        }

        protected override void DeadState(TimeSpan deltat)
        {
            if (flags.BeingDaed == false)
            {
                particleSystem.AddEmitter(new ExplosionEmitter(position));
            }
            base.DeadState(deltat);
        }

        protected override void TravelingState(TimeSpan deltat)
        {
            if (enemy != null)
            {
                attack();
            }

            base.TravelingState(deltat);
        }

        protected override void AttackingState(TimeSpan deltat)
        {
            flags.Attacked = false;

            if (enemy != null)
            {
                //if ((position - enemy.Position).Length() > range /*&& mood == Moodes.Aggressive*/)
                {
                    setvalues();
                    move(deltat);
                }
                attack();
                base.AttackingState(deltat);
            }
            else
                if(findtarget() == false)
                    State = UnitState.Idle;
        }

        #endregion

        #region metody draw i update
        public override void Draw(ExtendedSpriteBatch exSpriteBatch)
        {
            float hieght = 40;
            //korpus
            Rectangle cliprect = new Rectangle(0, 0, 150, 100);
            exSpriteBatch.Draw(texture, position, cliprect, color, realrotation, new Vector2(cliprect.Width, cliprect.Height) / 2, 1, SpriteEffects.None, 0.11f);

            if (State != UnitState.Dead)
            {
                //i cień kuprusu
                cliprect = new Rectangle(0, 0, 150, 100);
                exSpriteBatch.Draw(texture, position + new Vector2(0, hieght), cliprect, Color.Black * 0.1f, realrotation, new Vector2(cliprect.Width, cliprect.Height) / 2, 1, SpriteEffects.None, 0.2f);

                Color tmp = new Color();
                switch (Team)
                {
                    case 1:
                        tmp = Color.MediumAquamarine;
                        break;
                    case 2:
                        tmp = Color.OrangeRed;
                        break;
                    default:
                        tmp = Color.White;
                        break;
                }
                // wirnik
                cliprect = new Rectangle(150, 0, 100, 100);
                exSpriteBatch.Draw(texture, position, cliprect, tmp, 0, new Vector2(cliprect.Width, cliprect.Height) / 2, 1, SpriteEffects.None, 0.1f);
                 
                //i cien wirnika
                cliprect = new Rectangle(150, 0, 100, 100);
                exSpriteBatch.Draw(texture, position + new Vector2(0, hieght), cliprect, Color.Black * 0.1f, 0, new Vector2(cliprect.Width, cliprect.Height) / 2, 1, SpriteEffects.None, 0.21f);
            }
            base.Draw(exSpriteBatch);
        }

        public override bool Update(TimeSpan deltat)
        {
            base.Update(deltat);
            return true;
        }

        #endregion
    }
}
